/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.commons.logging;

import com.google.gwt.core.client.GWT;
import com.googlecode.gwt.logging.api.client.impl.CommonsLogAdapter;
import com.googlecode.gwt.logging.api.client.LogWriterFactory;


/**
 * <p>Factory for creating {@link Log} instances, with discovery and
 * configuration features similar to that employed by standard Java APIs
 * such as JAXP.</p>
 * <p/>
 * <p><strong>IMPLEMENTATION NOTE</strong> - This implementation is heavily
 * based on the SAXParserFactory and DocumentBuilderFactory implementations
 * (corresponding to the JAXP pluggability APIs) found in Apache Xerces.</p>
 *
 * @author Craig R. McClanahan
 * @author Costin Manolache
 * @author Richard A. Sitze
 * @version $Revision: 593798 $ $Date: 2007-11-10 18:40:43 +0100 $
 */

public final class LogFactory {

    private static final LogFactory FACTORY = new LogFactory();

    private LogFactory() {
        // empty
    }

    /**
     * Convenience method to derive a name from the specified class and
     * call <code>getInstance(String)</code> with it.
     *
     * @param aClass Class for which a suitable Log name will be derived
     * @return logger object
     * @throws LogConfigurationException if a suitable <code>Log</code>
     *                                   instance cannot be returned
     */
    public Log getInstance(Class aClass)
            throws LogConfigurationException {
        return getInstance(aClass.getName());
    }


    /**
     * <p>Construct (if necessary) and return a <code>Log</code> instance,
     * using the factory's current set of configuration attributes.</p>
     * <p/>
     * <p><strong>NOTE</strong> - Depending upon the implementation of
     * the <code>LogFactory</code> you are using, the <code>Log</code>
     * instance you are returned may or may not be local to the current
     * application, and may or may not be returned again on a subsequent
     * call with the same name argument.</p>
     *
     * @param name Logical name of the <code>Log</code> instance to be
     *             returned (the meaning of this name is only known to the underlying
     *             logging implementation that is being wrapped)
     * @return logger object
     * @throws LogConfigurationException if a suitable <code>Log</code>
     *                                   instance cannot be returned
     */
    public Log getInstance(String name)
            throws LogConfigurationException {
        return new CommonsLogAdapter(GWT.<LogWriterFactory>create(LogWriterFactory.class).getLogWriter(name));
    }


    /**
     * <p>Construct (if necessary) and return a <code>LogFactory</code>
     * instance, using the following ordered lookup procedure to determine
     * the name of the implementation class to be loaded.</p>
     * <ul>
     * <li>The <code>org.apache.commons.logging.LogFactory</code> system
     * property.</li>
     * <li>The JDK 1.3 Service Discovery mechanism</li>
     * <li>Use the properties file <code>commons-logging.properties</code>
     * file, if found in the class path of this class.  The configuration
     * file is in standard <code>java.util.Properties</code> format and
     * contains the fully qualified name of the implementation class
     * with the key being the system property defined above.</li>
     * <li>Fall back to a default implementation class
     * (<code>org.apache.commons.logging.impl.LogFactoryImpl</code>).</li>
     * </ul>
     * <p/>
     * <p><em>NOTE</em> - If the properties file method of identifying the
     * <code>LogFactory</code> implementation class is utilized, all of the
     * properties defined in this file will be set as configuration attributes
     * on the corresponding <code>LogFactory</code> instance.</p>
     * <p/>
     * <p><em>NOTE</em> - In a multithreaded environment it is possible
     * that two different instances will be returned for the same
     * classloader environment.
     * </p>
     *
     * @return logger factory
     * @throws LogConfigurationException if the implementation class is not
     *                                   available or cannot be instantiated.
     */
    public static LogFactory getFactory()
            throws LogConfigurationException {
        return FACTORY;
    }


    /**
     * Convenience method to return a named logger, without the application
     * having to care about factories.
     *
     * @param aClass Class from which a log name will be derived
     * @return logger object
     * @throws LogConfigurationException if a suitable <code>Log</code>
     *                                   instance cannot be returned
     */
    public static Log getLog(Class aClass)
            throws LogConfigurationException {
        return FACTORY.getInstance(aClass);

    }


    /**
     * Convenience method to return a named logger, without the application
     * having to care about factories.
     *
     * @param name Logical name of the <code>Log</code> instance to be
     *             returned (the meaning of this name is only known to the underlying
     *             logging implementation that is being wrapped)
     * @return logger object
     * @throws LogConfigurationException if a suitable <code>Log</code>
     *                                   instance cannot be returned
     */
    public static Log getLog(String name)
            throws LogConfigurationException {
        return FACTORY.getInstance(name);
    }
}
